#include <bitset>
#include <iostream>

using namespace std;

int main()
{
    bitset<32> bitvec(1U);              // 32 位；低位为 1，剩余位为 0
    bool is_set = bitvec.any();         // true，因为有 1 位置位
    bool is_not_set = bitvec.none();    // false，因为有 1 位置位了
    bool all_set = bitvec.all();        // false，因为只有 1 位置位
    size_t onBits = bitvec.count();     // 返回 1
    size_t sz = bitvec.size();          // 返回 32
    bitvec.flip();      // 翻转 bitvec 中的所有位
    bitvec.reset();     // 将所有位复位
    bitvec.set();       // 将所有位置位

    int i = 3;
    bitvec.flip(0);     // 翻转第一位
    bitvec.set(bitvec.size() - 1);      // 置位最后一位
    bitvec.set(0, 0);   // 复位第一位
    bitvec.reset(i);    // 复位第 i 位
    bitvec.test(0);     // 返回 false，因为第一位是复位的

    bitvec[0] = 0;          // 将第一位复位
    bitvec[31] = bitvec[0]; // 将最后一位设置为与第一位一样
    bitvec[0].flip();       // 翻转第一位
    ~bitvec[0];             // 等价操作，也是翻转第一位
    bool b = bitvec[0];     // 将 bitvec[0] 的值转换为 bool 类型

    /**
     * 只有当 bitset 的大小小于等于对应的大小时，才能使用这两个操作，
     * 否则会抛出一个 overflow_error 异常
     * to_ulong 为 unsigned long
     * to_ullong 为 unsigned long long
     */
    unsigned long ulong = bitvec.to_ulong();
    cout << "ulong = " << ulong << endl;

    bitset<16> bits;
    cin >> bits; // 从 cin 读取最多 16 个 0 或 1
    cout << "bits: " << bits << endl; // 打印刚刚读取的内容

    bool status;
    // 使用位运算符的版本
    unsigned long quizA = 0;            // 此值被当作位集合使用
    quizA |= 1UL << 27;                 // 指出第 27 个学生通过了测验
    status = quizA & (1UL << 27);       // 检查第 27 个学生是否通过了测验
    quizA &= ~(1UL << 27);              // 第 27 个学生未通过测验
    // 使用标准库类 bitset 完成等价的工作
    bitset<30> quizB;           // 每个学生分配一位，所有位都被初始化为 0
    quizB.set(27);              // 指出第 27 个学生通过了测验
    status = quizB[27];         // 检查第 27 个学生是否通过了测验
    quizB.reset(27);            // 第 27 个学生未通过测验
}